﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using System.Web.Routing;
using System.Web.Mvc;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using System.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;


namespace Unity
{
    public interface IA
    {
        string Write();
    }
    public class A :IA
    {
        public string Write()
        {
            return "A";
        }
    }
    public interface IB
    {
        string Write();
    }
    public class B : IB
    {
        public string Write()
        {
            return "B";
        }
    }
    public interface IC
    {
        string Write();
    }
    public class C : IC
    {
        public string Write()
        {
            return "C";
        }
    }
    public interface IService
    {
        string AWrite();
        string BWrite();
        string CWrite(IC C);
    }
    public class Service : IService
    {
        [Dependency]
        public IA A { get; set; }
        public IB B { get; set; }
        public IC C { get; set; }

        public Service(IB B)
        {
            this.B = B;
        }

        public string AWrite()
        {
            return A.Write();
        }
        public string BWrite()
        {
            return B.Write();
        }
        public string CWrite(IC C)
        {
            this.C = C;
            return this.C.Write();
        }
    }

    public class UnityDependencyResolver : IDependencyResolver
    {
        public IUnityContainer containers;

        public UnityDependencyResolver(IUnityContainer containers)
        {
            this.containers = containers;
        }

        public object GetService(Type serviceType)
        {
            if (this.containers.IsRegistered(serviceType))
                return this.containers.Resolve(serviceType);
            return null;

        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            try
            {
                return this.containers.ResolveAll(serviceType);
            }
            catch (Exception)
            {
                return new List<object>();
            }
        }
    }
    public class UnityControlFactory:DefaultControllerFactory
    {
        IUnityContainer containes;
        public UnityControlFactory (IUnityContainer container)
	    {
            this.containes = container;
	    }
        protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
        {
            return DependencyResolver.Current.GetService(controllerType) as IController;
        }
    }
    public class UnityControllerFactory : DefaultControllerFactory
    {
        static object syncHelper = new object();
        static Dictionary<string, IUnityContainer> containers = new Dictionary<string, IUnityContainer>();
        public IUnityContainer UnityContainer { get; private set; }
        public UnityControllerFactory(string containerName = "")
        {
            if (containers.ContainsKey(containerName))
            {
                this.UnityContainer = containers[containerName];
                return;
            }
            lock (syncHelper)
            {
                if (containers.ContainsKey(containerName))
                {
                    this.UnityContainer = containers[containerName];
                    return;
                }
                IUnityContainer container = new UnityContainer();
                //配置UnityContainer
                UnityConfigurationSection configSection = ConfigurationManager.GetSection(UnityConfigurationSection.SectionName) as UnityConfigurationSection;
                if (null == configSection && !string.IsNullOrEmpty(containerName))
                {
                    throw new ConfigurationErrorsException("The <unity> configuration section does not exist.");
                }
                if (null != configSection)
                {
                    if (string.IsNullOrEmpty(containerName))
                    {
                        configSection.Configure(container);
                    }
                    else
                    {
                        configSection.Configure(container, containerName);
                    }
                }
                containers.Add(containerName, container);
                this.UnityContainer = containers[containerName];
            }
        }
        protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
        {
            if (null == controllerType)
            {
                return null;
            }
            return this.UnityContainer.Resolve(controllerType) as IController;
        }
    }

}